package org.gjy.m8.concurrent.cf;

import java.sql.*;
import java.util.concurrent.*;

/**
 * @author gjy
 * @version 1.0
 * @since 2025-10-09 14:49:19
 */
public class Cf3Test {

    // 数据库连接配置
    private static final String DB_URL = "jdbc:mysql://localhost:3306/python_db";
    private static final String USERNAME = "root";
    private static final String PASSWORD = "Oracle@12";

    public static void main(String[] args) {
        ExecutorService executor = Executors.newSingleThreadExecutor();

        try {
            // 执行带超时的SQL任务
            String result = executeSQLTaskWithTimeout(executor, 3, TimeUnit.SECONDS);
            System.out.println("SQL任务执行结果: " + result);
        } catch (TimeoutException e) {
            System.out.println("SQL任务超时被取消");
        } catch (Exception e) {
            System.out.println("SQL任务执行异常: " + e.getMessage());
            e.printStackTrace();
        } finally {
            executor.shutdown();
        }
    }

    public static String executeSQLTaskWithTimeout(ExecutorService executor, long timeout, TimeUnit unit)
            throws TimeoutException, ExecutionException, InterruptedException {

        // 创建SQL任务
        Callable<String> sqlTask = () -> {
            Connection connection = null;
            Statement statement = null;
            ResultSet resultSet = null;

            try {
                // 建立数据库连接
                System.out.println("正在建立数据库连接...");
                connection = DriverManager.getConnection(DB_URL, USERNAME, PASSWORD);
                System.out.println("数据库连接建立成功");

                // 创建Statement
                statement = connection.createStatement();

                // 设置查询超时（数据库层面的超时）
                statement.setQueryTimeout((int) unit.toSeconds(timeout));

                // 模拟长时间运行的SQL查询
                String sql = "SELECT SLEEP(5) as result"; // MySQL特有的函数，会休眠5秒

                System.out.println("开始执行SQL查询...");
                resultSet = statement.executeQuery(sql);

                StringBuilder result = new StringBuilder();
                while (resultSet.next()) {
                    result.append("查询结果: ").append(resultSet.getString("result")).append("\n");
                }

                System.out.println("SQL查询执行完成");
                return result.toString();

            } catch (SQLException e) {
                // 检查是否是由于取消或超时导致的异常
                if (e.getMessage().contains("cancel") || e.getMessage().contains("timeout")) {
                    System.out.println("SQL执行被取消或超时: " + e.getMessage());
                    throw new RuntimeException("SQL执行超时", e);
                } else {
                    System.out.println("SQL执行异常: " + e.getMessage());
                    throw e;
                }
            } finally {
                // 关闭资源
                try {
                    if (resultSet != null) resultSet.close();
                    if (statement != null) statement.close();
                    if (connection != null) connection.close();
                    System.out.println("数据库资源已释放");
                } catch (SQLException e) {
                    System.out.println("关闭数据库资源时出错: " + e.getMessage());
                }
            }
        };

        // 提交任务并获取Future
        Future<String> future = executor.submit(sqlTask);

        try {
            // 在指定时间内获取结果
            return future.get(timeout, unit);
        } catch (TimeoutException e) {
            System.out.println("任务超时，正在取消SQL执行...");

            // 取消任务（这会中断执行线程）
            boolean cancelled = future.cancel(true);
            System.out.println("任务取消状态: " + cancelled);

            // 注意：future.cancel(true) 会中断线程，但不能直接取消SQL执行
            // SQL取消需要在任务内部处理中断信号
            throw e;
        }
    }

}
